package com.qf.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.*;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.qf.common.BusinessException;
import org.springframework.boot.autoconfigure.security.oauth2.resource.OAuth2ResourceServerProperties;

import java.util.Calendar;
import java.util.Map;
import java.util.Set;

public class JWTUtils {

    private static String sign = "2101-shop"; // 不能暴出去

    /**
     *创建token
     * @param param 用户的数据
     * @param ep 过期时间
     * @return token字符串
     */
    public static String createToken(Map<String, String> param, Integer ep) {

        // 1.生成的一个token
        JWTCreator.Builder builder = JWT.create();

        // 2.用户创建token的时候是否传递的参数
        if (param != null) {
            Set<Map.Entry<String, String>> entries = param.entrySet();
            for (Map.Entry<String, String> entry : entries) {
                String key = entry.getKey(); // 参数的name
                String value = entry.getValue(); // 参数的值
                builder.withClaim(key, value);
            }
        }

        // 3.设置过期时间
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.SECOND, 60 * 30); // 默认是30m
        if (ep != null) {
            calendar.set(Calendar.SECOND, ep);
        }
        builder.withExpiresAt(calendar.getTime());

        // 4.用户的签名
        String token = builder.sign(Algorithm.HMAC256(JWTUtils.sign));

        return token;
    }

    /**
     * 延签
     * @param token 需要被盐值的tokne字符串
     * @throws BusinessException
     */
    public static DecodedJWT verifier(String token) throws BusinessException {

        // 1.获取盐值的对象
        JWTVerifier build = JWT.require(Algorithm.HMAC256(sign)).build();
        try {
            return build.verify(token);
        } catch (AlgorithmMismatchException e) { // 签名算法不一致
            throw new BusinessException(1007, "签名算法不一致");
        } catch (JWTDecodeException e) { // token字符串不一致
            throw new BusinessException(1008, "token字符串不一致");
        } catch (SignatureVerificationException e) { // 签名不一致
            throw new BusinessException(1009, "签名不一致");
        } catch (TokenExpiredException e) { // token超时
            throw new BusinessException(1010, "token超时");
        } catch (JWTVerificationException e) { // 延签失败
            throw new BusinessException(1011, "延签失败");
        }
    }

    /**
     * 获取token中的内容
     * @param verify 延签成功后的对象
     * @param name 参数的key
     * @return
     */
    public static String getClaim(DecodedJWT verify,String name){
        return verify.getClaim(name).asString();
    }
}
